/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.api.be;

import com.inspur.edp.bef.api.lcp.IStandardLcp;
import com.inspur.edp.bef.api.services.IBELogger;
import com.inspur.edp.cef.api.dataType.entity.ICefEntityContext;
import com.inspur.edp.cef.entity.changeset.IChangeDetail;
import com.inspur.edp.cef.entity.entity.IEntityData;

/**
 * 业务实体的上下文信息接口，用于在主表实体动作中获取当前实体数据等信息。
 * <p>
 * 一般用于主表实体动作。在实体动作中如需修改当前实体数据，可以参考如下写法：
 * <blockquote><pre>
 *     ((IXxxData)getBEContext().getCurrentData()).setCode(“xxx”);
 *     ((IXxxData)getBEContext().getCurrentData()).getCode();//以上适用于生成型
 *     getBEContext().getCurrentData().setValue(“Code”, "xxx");
 *     getBEContext().getCurrentData().getValue("Code");//以上适用于解析型
 * </pre></blockquote>
 */
public interface IBEContext extends ICefEntityContext, IBENodeEntityContext {
// #region 属性

  /**
   * 获取原始实体数据
   * <p>此方法返回值不包含任何未持久化的修改，换句话说，就是与数据库中的数据保持一致。
   * <p>如果数据是新增的，那么在执行保存之前，此方法返回值总为{@code null}。
   * <p>相反，如果数据被删除，那么在执行保存之前，此方法返回值总不为{@code null}。
   * <p>原始实体数据是只读的不允许修改，如果修改将会引发{@link com.inspur.edp.cef.entity.accessor.base.ReadonlyDataException}异常。
   */
  IEntityData getOriginalData();

  /**
   * 获取事务级实体数据
   * 事务级实体数据，包含未进行持久化的已被接受的变更，但不包含正在执行的动作所产生的变更。
   * <p>假设当前正在执行保存动作：
   * <p>如果在当前动作执行之前数据已被删除，那么当前动作执行期间此方法返回值为{@code null}；
   * <p>如果数据当前动作执行期间被删除，那么此方法返回值不为{@code null}；
   * <p>事务级实体数据是只读的不允许修改，如果修改将会引发{@link com.inspur.edp.cef.entity.accessor.base.ReadonlyDataException}异常。
   */
  IEntityData getTransactionData();

  /**
   * 获取当前请求下还未提交内存的实体数据
   * 获取当前实体数据
   * <p>相比{@link #getTransactionData()}，此方法返回值包含当前正在执行的动作中所产生的修改，
   * 而{@link #getTransactionData()}不包含。例如，假设当前动作是修改，修改内容为将X字段的值由A修改为B，在动作执行过程中，
   * {@code getCurrentData()}方法返回值上的X字段值为B，{@code getTransactionData()}方法返回值上的X字段值为A。
   * <p>如果数据被删除，那么此方法返回{@code null}，如需获取删除前的数据：
   * <ul><li>如果数据在当前动作执行期间被删除，应使用{@link #getTransactionData()}获取；
   * <li>如果数据在当前动作执行之前已被删除，应使用{@link #getOriginalData()}获取。</ul>
   */
  IEntityData getCurrentData();

  /** 获取当前实体数据的唯一标识  */
  @Override
  String getID();

  /** 获取当前业务实体  */
  IBusinessEntity getBizEntity();

  /** 获取当前请求下因修改触发了联动计算而使实体数据发生变化产生的变更集  */
  @Override
  IChangeDetail getCurrentTemplateChange();

  /** 获取内存中已提交成功的实体数据变更集  */
  IChangeDetail getTransactionalChange();

  /**
   * 当前请求下还未提交内存的实体数据变更集，CurrentChange可认为是ChangeFromModify与CurrentTemplateChange的合集
   */
  IChangeDetail getCurrentChange();


  /**
   * 判断当前实体数据是否已加载
   *
   * @return
   */
  boolean hasData();

  /**
   * 判断当前实体数据是否加锁
   *
   * @return
   */
  boolean isLocked();

  /**
   * 判断当前实体数据是否是删除状态
   *
   * @return
   */
  boolean isDeleted();

  /**
   * 获取当前日志记录
   *
   * @return 日志记录接口
   */
  IBELogger getLogger();

  /**
   * 判断当前实体数据是否是新增状态
   *
   * @return
   */
  boolean isNew();

  /**
   * 数据权限检查
   *
   * @param actionCode 动作编号
   */
  void checkDataAuthority(String actionCode);
}
